package com.zl.autocode.service.autocode.impl;

import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zl.autocode.common.constant.AutocodeConfigC;
import com.zl.autocode.common.constant.AutocodeEnum;
import com.zl.autocode.common.constant.AutocodeProperties;
import com.zl.autocode.dao.autocode.ZLCfgGenerateDtlMapper;
import com.zl.autocode.dao.autocode.ZLCfgGenerateMapper;
import com.zl.autocode.dao.autocode.ZlDictDtlMapper;
import com.zl.autocode.dao.autocode.ZlProjectMapper;
import com.zl.autocode.dao.autocode.ZlProjectModuleMapper;
import com.zl.autocode.dao.autocode.ZlTableColumnMapper;
import com.zl.autocode.dao.autocode.ZlTableMapper;
import com.zl.autocode.dao.autocode.ZlTemplateDtlMapper;
import com.zl.autocode.dao.autocode.ZlTemplateMapper;
import com.zl.autocode.dao.autocode.ZlValidationMapper;
import com.zl.autocode.dao.autocode.ZlWebComponentMapper;
import com.zl.autocode.dto.autocode.project.ReqProjectAddDTO;
import com.zl.autocode.dto.autocode.project.ReqProjectDelDTO;
import com.zl.autocode.dto.autocode.project.ReqProjectDetailDTO;
import com.zl.autocode.dto.autocode.project.ReqProjectEditDTO;
import com.zl.autocode.dto.autocode.project.ReqProjectQueryDTO;
import com.zl.autocode.dto.autocode.project.ReqProjectStateDTO;
import com.zl.autocode.dto.autocode.project.ResProjectAddDTO;
import com.zl.autocode.dto.autocode.project.ResProjectDelDTO;
import com.zl.autocode.dto.autocode.project.ResProjectDetailDTO;
import com.zl.autocode.dto.autocode.project.ResProjectEditDTO;
import com.zl.autocode.dto.autocode.project.ResProjectQueryDTO;
import com.zl.autocode.dto.autocode.project.ResProjectStateDTO;
import com.zl.autocode.dto.autocode.project.ResProjectVO2;
import com.zl.autocode.entity.autocode.ZLCfgGenerate;
import com.zl.autocode.entity.autocode.ZlDictDtl;
import com.zl.autocode.entity.autocode.ZlProject;
import com.zl.autocode.entity.autocode.ZlTemplate;
import com.zl.autocode.entity.autocode.ZlWebComponent;
import com.zl.autocode.entity.autocode.po.ZlProjectVo;
import com.zl.autocode.service.autocode.IProjectService;
import com.zl.autocode.service.base.AutocodeBaseManager;
import com.zl.common.dto.ReqDTO;
import com.zl.common.dto.pagination.PageReqVO;
import com.zl.common.enums.resp.GlobalRespEnum;
import com.zl.common.exception.BizException;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;

/**
 * 项目配置
 * @author ZL
 */
@Service("autocodeProjectService")
public class ProjectServiceImpl extends AutocodeBaseManager implements IProjectService {

    @Autowired
    private ZlProjectMapper projectMapper;
    @Autowired
    private ZlProjectModuleMapper projectModuleMapper;
    @Autowired
    private AutocodeProperties autocodeProperties;
    @Autowired
    protected DataSource dynamicDataSource;
    @Autowired
    private ZlTableMapper tableMapper;
    @Autowired
    private ZlTableColumnMapper tableColumnMapper;
    @Autowired
    private ZlTemplateMapper templateMapper;
    @Autowired
    private ZlTemplateDtlMapper templateDtlMapper;
    @Autowired
    private ZlValidationMapper validationMapper;
    @Autowired
    private ZlWebComponentMapper webComponentMapper;
    @Autowired
    private ZLCfgGenerateMapper cfgGenerateMapper;
    @Autowired
    private ZLCfgGenerateDtlMapper cfgGenerateDtlMapper;
    @Autowired
    private ZlDictDtlMapper dictDtlMapper;
    
    @Override
    public ResProjectQueryDTO queryProjectList(ReqDTO<ReqProjectQueryDTO> reqInfo) throws Exception{
        // TODO Auto-generated method stub
        ReqProjectQueryDTO reqData = reqInfo.getReqData();
        PageReqVO page = pageHandle(reqInfo.getPageInfo());//处理分页数据
        ResProjectQueryDTO resDTO = BeanUtil.copyProperties(page, ResProjectQueryDTO.class);
        if(StringUtils.isNotBlank(reqData.getProjectTitle())){
            reqData.setProjectTitle("%"+reqData.getProjectTitle()+"%");
        }
        Map<String,Object> paramMap = BeanUtil.beanToMap(reqData,false,true);
        
        Page<Object> pageHp = PageHelper.startPage(page.getPage(), page.getLimit(),page.getSortorder());
        List<ZlProjectVo> list = projectMapper.selectListPage(paramMap);
        resDTO.setData(BeanUtil.copyToList(list, ResProjectVO2.class));
        resDTO.setCount(pageHp.getTotal());
        
        return resDTO;
    }
    
    @Override
    public ResProjectDetailDTO queryProjectDetail(ReqDTO<ReqProjectDetailDTO> reqInfo) throws Exception{
        // TODO Auto-generated method stub
        ReqProjectDetailDTO reqData = reqInfo.getReqData();
        ResProjectDetailDTO res = new ResProjectDetailDTO();
        
        Map<String,Object> paramMap = new HashMap<>();
        paramMap = BeanUtil.beanToMap(reqData);
        ZlProject view = projectMapper.selectOneByMap(paramMap);
        BeanUtil.copyProperties(view, res);
        return res;
    }
    
    @Override
    public ResProjectAddDTO insertProjectInfo(ReqDTO<ReqProjectAddDTO> reqInfo) throws Exception{
        // TODO Auto-generated method stub
        ReqProjectAddDTO reqData = reqInfo.getReqData();
        ResProjectAddDTO res = new ResProjectAddDTO();
        Date time = getSystemTime().getDate();
        
        ZlProject record = new ZlProject();
        BeanUtil.copyProperties(reqData, record);
        
        initCreateInfo(record, reqInfo, time);
        record.setProjectId(IdUtil.simpleUUID());
        record.setSqlPath(filePath(autocodeProperties.getAutocodePathMajor(),autocodeProperties.getAutocodePathProject()
                ,new String[]{record.getProjectId().toString()+"---10",AutocodeConfigC.PATH_CHILDREN_SQL}));
        record.setPdmPath(filePath(autocodeProperties.getAutocodePathMajor(),autocodeProperties.getAutocodePathProject()
                ,new String[]{record.getProjectId().toString()+"---10",AutocodeConfigC.PATH_CHILDREN_PDM}));
        
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("projectId",record.getProjectId());
        //检查主键是否冲突
        if(projectMapper.countExistKey(paramMap)>0){
            throw new BizException(GlobalRespEnum.DUPLICATE_PRIMARY_KEY);
        }
        
        projectMapper.insertSelective(record);
        
        paramMap.clear();
        paramMap.put("dictType","component.componentType");
        List<ZlDictDtl> codes=dictDtlMapper.selectListByMapForSelectItem(paramMap);
        if(codes!=null&&codes.size()>0){
            for(ZlDictDtl x:codes){
                ZlWebComponent componentRecord = new ZlWebComponent();
                initCreateInfo(componentRecord, reqInfo, time);
                componentRecord.setComponentId(IdUtil.simpleUUID());
                componentRecord.setProjectId(record.getProjectId());
                componentRecord.setComponentType(x.getDictDtlNo());
                componentRecord.setComponentCode(x.getDictDtlNo());
                componentRecord.setComponentTitle(x.getDictDisplay1());
                webComponentMapper.insertSelective(componentRecord);
            }
        }
        paramMap.clear();
        paramMap.put("projectId",record.getProjectId());
        ZlProject keyInfo = projectMapper.selectOneByMap(paramMap);
        BeanUtil.copyProperties(keyInfo, res);
        
        return res;
    }
    
    @Override
    public ResProjectEditDTO updateProjectInfo(ReqDTO<ReqProjectEditDTO> reqInfo) throws Exception{
        // TODO Auto-generated method stub
        ReqProjectEditDTO reqData = reqInfo.getReqData();
        ResProjectEditDTO res = new ResProjectEditDTO();
        Date time = getSystemTime().getDate();
        
        ZlProject record = new ZlProject();
        BeanUtil.copyProperties(reqData, record);
        
        initUpdateInfo(record, reqInfo, time);
        
        projectMapper.updateByPrimaryKeySelective(record);
        
        String cdskey = AutocodeConfigC.DDS_KEY + record.getProjectId().toString();
        DynamicRoutingDataSource dynamicRoutingDataSource = (DynamicRoutingDataSource)dynamicDataSource;
        dynamicRoutingDataSource.removeDataSource(cdskey);
        
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("projectId",record.getProjectId());
        ZlProject keyInfo = projectMapper.selectOneByMap(paramMap);
        BeanUtil.copyProperties(keyInfo, res);
        
        return res;
    }
    
    @Override
    public ResProjectDelDTO deleteProjectInfo(ReqDTO<ReqProjectDelDTO> reqInfo) throws Exception{
        // TODO Auto-generated method stub
        ReqProjectDelDTO reqData = reqInfo.getReqData();
        ResProjectDelDTO res = new ResProjectDelDTO();
        Date time = getSystemTime().getDate();
        
        Map<String,Object> paramMap = BeanUtil.beanToMap(reqData);
        if(projectModuleMapper.countExistKey(paramMap) > 0){
            throw new BizException(GlobalRespEnum.DELETION_NOT_ALLOWED);
        }       
        ZlProject project = projectMapper.selectOneByMap(paramMap);
        if(StringUtils.isNotBlank(project.getPdmPath())
                && project.getPdmPath().contains(autocodeProperties.getAutocodePathMajor()) 
                && project.getPdmPath().contains(autocodeProperties.getAutocodePathProject())){
            File newFile = new File(handlerRootPath(project.getPdmPath()));
            if(newFile.exists() && newFile.isDirectory()
                    && newFile.getParentFile().getPath().contains(autocodeProperties.getAutocodePathProject())){
                FileUtil.del(newFile.getParentFile());
            }
        }
        if(StringUtils.isNotBlank(project.getSqlPath())
                && project.getSqlPath().contains(autocodeProperties.getAutocodePathMajor()) 
                && project.getSqlPath().contains(autocodeProperties.getAutocodePathProject())){
            File newFile  = new File(handlerRootPath(project.getSqlPath()));
            if(newFile.exists() && newFile.isDirectory() 
                    && newFile.getParentFile().getPath().contains(autocodeProperties.getAutocodePathProject())){
                FileUtil.del(newFile.getParentFile());
            }
        }
        projectMapper.deleteByMap(paramMap);
        
        String cdskey = AutocodeConfigC.DDS_KEY + reqData.getProjectId().toString();
        DynamicRoutingDataSource dynamicRoutingDataSource = (DynamicRoutingDataSource)dynamicDataSource;
        dynamicRoutingDataSource.removeDataSource(cdskey);
        
        return res;
    }
    
    @Override
    public ResProjectStateDTO updateProjectState(ReqDTO<ReqProjectStateDTO> reqInfo) throws Exception{
        // TODO Auto-generated method stub
        ReqProjectStateDTO reqData = reqInfo.getReqData();
        ResProjectStateDTO res = new ResProjectStateDTO();
        Date time = getSystemTime().getDate();
         
        ZlProject record = new ZlProject();
        BeanUtil.copyProperties(reqData, record);
        initUpdateInfo(record, reqInfo, time);
        projectMapper.updateByPrimaryKeySelective(record);
         
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("projectId",record.getProjectId());
        ZlProject keyInfo = projectMapper.selectOneByMap(paramMap);
        BeanUtil.copyProperties(keyInfo, res);
        
        return res;
    }
    
    @Override
    public ResProjectDelDTO deleteProjectAndModule(ReqDTO<ReqProjectDelDTO> reqInfo) throws Exception{
        // TODO Auto-generated method stub
        ReqProjectDelDTO reqData = reqInfo.getReqData();
        ResProjectDelDTO res = new ResProjectDelDTO();
        Date time = getSystemTime().getDate();
        
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("projectId",reqData.getProjectId());
        
        paramMap = BeanUtil.beanToMap(reqData);
        ZlProject project = projectMapper.selectOneByMap(paramMap);
        if(StringUtils.isNotBlank(project.getPdmPath())
                && project.getPdmPath().contains(autocodeProperties.getAutocodePathMajor()) 
                && project.getPdmPath().contains(autocodeProperties.getAutocodePathProject())){
            File newFile = new File(handlerRootPath(project.getPdmPath()));
            if(newFile.exists() && newFile.isDirectory()
                    && newFile.getParentFile().getPath().contains(autocodeProperties.getAutocodePathProject())){
                FileUtil.del(newFile.getParentFile());
            }
        }
        if(StringUtils.isNotBlank(project.getSqlPath())
                && project.getSqlPath().contains(autocodeProperties.getAutocodePathMajor()) 
                && project.getSqlPath().contains(autocodeProperties.getAutocodePathProject())){
            File newFile  = new File(handlerRootPath(project.getSqlPath()));
            if(newFile.exists() && newFile.isDirectory() 
                    && newFile.getParentFile().getPath().contains(autocodeProperties.getAutocodePathProject())){
                FileUtil.del(newFile.getParentFile());
            }
        }
        List<ZLCfgGenerate> cfgGenerateList = cfgGenerateMapper.selectListByMap(paramMap);
        List<ZlTemplate> templateList = templateMapper.selectListByMap(paramMap);
        for(ZLCfgGenerate cfgGenerate:cfgGenerateList){
            if(StringUtils.isNotBlank(cfgGenerate.getCfgGeneratePath())
                    && cfgGenerate.getCfgGeneratePath().contains(autocodeProperties.getAutocodePathMajor()) 
                    && cfgGenerate.getCfgGeneratePath().contains(autocodeProperties.getAutocodePathGenerate())){
                FileUtil.del(handlerRootPath(cfgGenerate.getCfgGeneratePath()));
            }
        }
        for(ZlTemplate template:templateList){
            if(StringUtils.isNotBlank(template.getTemplatePath())
                    && template.getTemplatePath().contains(autocodeProperties.getAutocodePathMajor()) 
                    && template.getTemplatePath().contains(autocodeProperties.getAutocodePathTemplate())){
                FileUtil.del(handlerRootPath(template.getTemplatePath()));
            }
        }
        
        projectMapper.deleteByMap(paramMap);
        projectModuleMapper.deleteByMap(paramMap);
        
        tableMapper.deleteByMap(paramMap);
        tableColumnMapper.deleteByMap(paramMap);
        templateMapper.deleteByMap(paramMap);
        templateDtlMapper.deleteByMap(paramMap);
        validationMapper.deleteByMap(paramMap);
        webComponentMapper.deleteByMap(paramMap);
        
        
        for(ZLCfgGenerate x:cfgGenerateList){
            paramMap.put("cfgGenerateId", x.getCfgGenerateId());
            cfgGenerateDtlMapper.deleteByMap(paramMap);
        }
        cfgGenerateMapper.deleteByMap(paramMap);
        
        String cdskey = AutocodeConfigC.DDS_KEY + reqData.getProjectId().toString();
        DynamicRoutingDataSource dynamicRoutingDataSource = (DynamicRoutingDataSource)dynamicDataSource;
        dynamicRoutingDataSource.removeDataSource(cdskey);
        
        return res;
    }
}